#region Usings

using System.Threading;
using System.Web;
using System.Web.Security;
using Karma.Framework.Core.Web;

#endregion

namespace Karma.Framework.Core.Security
{
    public delegate IPrincipal PrincipalRepositoryDelegate(string usr, string domain);

    public class Context
    {
        public static PrincipalRepositoryDelegate PrincipalRepository
        {
            get
            {
                return (PrincipalRepositoryDelegate) Get ("_PrincipalRepository_");
            }
            set
            {
                Set("_PrincipalRepository_", value);
            }
        }

        public static IPrincipal User
        {
            get
            {
                if (GetContext().User is IPrincipal)
                {
                    return (IPrincipal) GetContext().User;
                }
                var username = (string) Get("Usuario");
                var domain = (string) Get("Dominio");
                var user = PrincipalRepository(username, domain);
                if (user == null)
                {
                    throw new SecurityException("No User data");
                }
                User = user;
                return user;
            }
            private set
            {
                GetContext().User = value;
                Thread.CurrentPrincipal = value;
            }
        }

        private static HttpContextBase GetContext()
        {
            return HttpContextFactory.GetHttpContext();
        }

        public static object Get(string key)
        {
            return GetContext().Items[key];
        }

        public static void Set(string key, object val)
        {
            if (GetContext().Items.Contains(key))
            {
                GetContext().Items[key] = val;
            }
            else
            {
                GetContext().Items.Add(key, val);
            }
        }

        public static void Initialize(IPrincipal user)
        {
            GetContext().Session["current.principal"] = user;
            GetContext().User = user;
            Thread.CurrentPrincipal = user;
        }

        public static void Release()
        {
            FormsAuthentication.SignOut();
        }
    }
}